package org.snaker.engine.spring.boot.autoconfigure;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.snaker.engine.Expression;
import org.snaker.engine.SnakerEngine;
import org.snaker.engine.TaskAccessStrategy;
import org.snaker.engine.core.*;
import org.snaker.engine.impl.GeneralAccessStrategy;
import org.snaker.engine.impl.JuelExpression;
import org.snaker.engine.spring.SpringJdbcAccess;
import org.snaker.engine.spring.SpringSnakerEngine;
import org.springframework.beans.factory.InitializingBean;
import org.springframework.boot.autoconfigure.condition.ConditionalOnClass;
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
import org.springframework.boot.context.properties.EnableConfigurationProperties;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.jdbc.support.lob.DefaultLobHandler;
import org.springframework.jdbc.support.lob.LobHandler;

import javax.sql.DataSource;

/**
 * Created by gyang on 2019/5/7.
 */
@Configuration
@ConditionalOnClass(DataSource.class)
@EnableConfigurationProperties({SnakerEngineProperties.class})
public class SnakerEngineAutoConfigure implements InitializingBean {

    private static final Logger LOGGER = LoggerFactory.getLogger(SnakerEngineAutoConfigure.class);

    @Bean
    @ConditionalOnMissingBean
    public LobHandler lobHandler() {
        return new DefaultLobHandler();
    }

    @Bean
    @ConditionalOnMissingBean
    public TaskAccessStrategy taskAccessStrategy() {
        return new GeneralAccessStrategy();
    }

    @Bean
    @ConditionalOnMissingBean
    public Expression expression() {
        return new JuelExpression();
    }

    @Bean
    @ConditionalOnMissingBean
    public SnakerEngine springSnakerEngine(DataSource dataSource, LobHandler lobHandler) {
        SpringJdbcAccess access = new SpringJdbcAccess();
        access.setLobHandler(lobHandler);
        access.setDataSource(dataSource);

        ProcessService processService = new ProcessService();
        processService.setAccess(access);

        OrderService orderService = new OrderService();
        orderService.setAccess(access);

        TaskService taskService = new TaskService();
        taskService.setAccess(access);

        ManagerService managerService = new ManagerService();
        managerService.setAccess(access);

        QueryService queryService = new QueryService();
        queryService.setAccess(access);

        SpringSnakerEngine engine = new SpringSnakerEngine();
        engine.setProcessService(processService);
        engine.setOrderService(orderService);
        engine.setTaskService(taskService);
        engine.setQueryService(queryService);
        engine.setManagerService(managerService);

        return engine;
    }

    @Override
    public void afterPropertiesSet() throws Exception {
        LOGGER.info("SnakerEngineAutoConfigure:afterPropertiesSet()!!!");
    }
}
